﻿
----------------------------
--      Localization      --
----------------------------

local L = GetLocale() == "deDE" and {
	["Flight Form"] = "Fluggestalt",
	["Swift Flight Form"] = "Schnelle Fluggestalt",
	["Ghost Wolf"] = "Geisterwolf",
	["Cat Form"] = "Katzengestalt",
	["Bear Form"] = "B\195\164rengestalt",
	["Dire Bear Form"] = "Terrorb\195\164rengestalt",
	["Travel Form"] = "Reisegestalt",
	["Moonkin Form"] = "Mondkingestalt",
	["Tree of Life"] = "Baum des Lebens",
} or {
	["Flight Form"] = "Flight Form",
	["Swift Flight Form"] = "Swift Flight Form",
	["Ghost Wolf"] = "Ghost Wolf",
	["Cat Form"] = "Cat Form",
	["Bear Form"] = "Bear Form",
	["Dire Bear Form"] = "Dire Bear Form",
	["Travel Form"] = "Travel Form",
	["Moonkin Form"] = "Moonkin Form",
	["Tree of Life"] = "Tree of Life",
}

------------------------------
--      Are you local?      --
------------------------------

local _, myclass = UnitClass("player")
local items, equipCheck, delayed, incombat, dbpc, mounted, isflight = {}, {}
local forms = myclass == "SHAMAN" and {L["Ghost Wolf"]} or myclass == "DRUID" and {L["Cat Form"], L["Bear Form"], L["Travel Form"], L["Dire Bear Form"], L["Flight Form"], L["Swift Flight Form"], L["Moonkin Form"], L["Tree of Life"]}
local itemstrs = {carrot = "item:11122:%d+:%d+:%d+", crop = "item:25653:%d+:%d+:%d+", charm = "item:32481:%d+:%d+:%d+", whip = "item:32863:%d+:%d+:%d+", spurs = "item:%d+:464:%d+:%d+", gloves = "item:%d+:930:%d+:%d+"}
local itemslots = {carrot = 13, crop = 13, whip = 13, charm = 13, spurs = 8, gloves = 10}
local unknowns = {carrot = 13, crop = 13, whip = 13, charm = 13, spurs = 8, gloves = 10}


-------------------------------------
--      Namespace Declaration      --
-------------------------------------

ESN_Mount = DongleStub("Dongle-1.0"):New("ESN_Mount", CreateFrame("Frame"))
if tekDebug then ESN_Mount:EnableDebug(1, tekDebug:GetFrame("ESN_Mount")) end


------------------------------
--      Dongle Methods      --
------------------------------

function ESN_Mount:Initialize()
	ESN_MountDB = ESN_MountDB or {BGsuspend = true, PvPsuspend = false, raidsuspend = false}
	self.db = ESN_MountDB

	ESN_MountItemSwapDB = ESN_MountItemSwapDB or {}
	dbpc = ESN_MountItemSwapDB
end


function ESN_Mount:Enable()
	self:ScanInventory()

	self:RegisterEvent("PLAYER_REGEN_DISABLED")
	self:RegisterEvent("PLAYER_REGEN_ENABLED")
	if myclass == "DRUID" then self:RegisterEvent("PLAYER_AURAS_CHANGED") end
	self:RegisterEvent("UNIT_INVENTORY_CHANGED")
	if forms then self:RegisterEvent("TAXIMAP_OPENED") end
end


-------------------------------
--      Mount Detection      --
-------------------------------

ESN_Mount:SetScript("OnUpdate", function(self)
	local m = IsMounted() or isflight
	if m == mounted then return end

	if m then
		self:Debug(1, "Mounted")
		self:Swap()
	else
		self:Debug(1, "Dismounted")
		if incombat then delayed = true
		else self:SwapReset() end
	end

	mounted = m
end)


------------------------------
--      Event Handlers      --
------------------------------

function ESN_Mount:TAXIMAP_OPENED()
	for _,form in pairs(forms) do CancelPlayerBuff(form) end
end


function ESN_Mount:PLAYER_REGEN_DISABLED()
	incombat = true
end


function ESN_Mount:PLAYER_REGEN_ENABLED()
	if delayed then self:SwapReset()
	else for i, link in pairs(equipCheck) do EquipItemByName(link) end end
	incombat, delayed = nil, nil
end


function ESN_Mount:PLAYER_AURAS_CHANGED()
	isflight = GetPlayerBuffTexture(L["Flight Form"]) or GetPlayerBuffTexture(L["Swift Flight Form"])
end


function ESN_Mount:UNIT_INVENTORY_CHANGED()
	for itemtype,link in pairs(equipCheck) do
		if link == GetInventoryItemLink("player", itemslots[itemtype]) then equipCheck[itemtype] = nil end
	end
end


-----------------------------------
--      Speed item swapping      --
-----------------------------------

function ESN_Mount:IsSuspended()
	-- While you can switch trinkets while inside an arena, you cannot once the match starts so we're disabled when inside arenas no matter what
	local _, instanceType = IsInInstance()
	return instanceType == "pvp" and IsMouseButtonDown("RightButton") and not self.db.BGsuspend
		or instanceType == "raid" and IsMouseButtonDown("RightButton") and not self.db.raidsuspend
		or UnitIsPVP("player") and instanceType ~= "pvp" and IsMouseButtonDown("RightButton") and not self.db.PvPsuspend
		or self.db.PvPsuspend and UnitIsPVP("player") and instanceType ~= "pvp" and not IsMouseButtonDown("RightButton")
		or self.db.BGsuspend and instanceType == "pvp" and not IsMouseButtonDown("RightButton")
		or self.db.raidsuspend and instanceType == "raid" and not IsMouseButtonDown("RightButton")
		or instanceType == "arena"
end


function ESN_Mount:Swap(reset)
	if self:IsSuspended() or not HasFullControl() then return end
	if next(unknowns) then self:ScanInventory() end

	for i, matchstr in pairs(itemstrs) do
		local link = GetInventoryItemLink("player", itemslots[i])
		if items[i] and (not link or not string.match(link, matchstr)) and ((i ~= "charm" and not isflight) or (i == "charm" and isflight)) then
			-- Makes sure we don't change our originally equipped item if it's our charm mainly this is for Flight Form since spamming it can mess up our original item
			if link ~= items[i] and equipCheck[i] ~= link then dbpc[i] = link end
			EquipItemByName(items[i])
		end
	end
end


-- Reset our gear to the unmounted version
function ESN_Mount:SwapReset()
	for i, link in pairs(dbpc) do
		dbpc[i] = nil
		equipCheck[i] = link
		EquipItemByName(link)
	end
end


----------------------------------
--      Speed item tracking     --
----------------------------------

function ESN_Mount:ScanInventory()
	for bag=0,4 do
		for slot=1,GetContainerNumSlots(bag) do
			local link = GetContainerItemLink(bag, slot)
			if link then
				-- Check if we need to add it to our list of mounted items
				for i, matchstr in pairs(itemstrs) do
					if string.match(link, matchstr) then
						unknowns[i] = nil
						items[i] = link
						break
					end
				end
			end
		end
	end
end
